package com.zrc.superframe_net.common.net

import android.content.Context
import android.util.Log
import com.zrc.superframe_net.interceptor.ProgressInterceptor
import com.zrc.superframe_net.common.download.NetDownloadApi
import com.zrc.superframe_net.common.download.NetDownloadProgressCallBack
import com.zrc.superframe_net.room.NetRoomUtil
import com.zrc.superframe_net.utils.HawkSpUtitls
import com.zrc.superframe_net.utils.NetUtils
import okhttp3.CookieJar
import okhttp3.EventListener
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory
import java.util.concurrent.TimeUnit
import kotlin.collections.ArrayList

/**
 * @Author: superman
 * @CreateTime: 6/27/21
 * @Describe:网络请求操作器
 */
class Net(val mBuilder: Builder) {
    var currentDownloadCount = 0 //当前正在下载的任务 当前正在下载的队列数量
    //创建Retroft isDownload 是否下载文件
    private fun crateRetrofit(isDownload: Boolean): Retrofit {
        val builder = OkHttpClient.Builder()//初始化OkHttp
        if (isDownload) { //下载
            builder.connectTimeout(mBuilder.down_Connection_Time.toLong(), TimeUnit.SECONDS)
            builder.addInterceptor(ProgressInterceptor(object : NetDownloadProgressCallBack {
                override fun update(url: String, readCount: Long, totalCount: Long, done: Boolean) {
                    mNetProgressListeners.forEach {
                        it.update(url, readCount, totalCount, done)
                    }
                }
            }))
        } else { //非下载
            builder.readTimeout(mBuilder.read_Timeout.toLong(), TimeUnit.SECONDS)
            builder.connectTimeout(mBuilder.connection_Timeout.toLong(), TimeUnit.SECONDS)
            builder.addInterceptor(with(HttpLoggingInterceptor()) {
                if (mBuilder.debug) {
                    this.level = HttpLoggingInterceptor.Level.BODY
                } else {
                    this.level = HttpLoggingInterceptor.Level.BASIC
                }
                this
            })
            mBuilder.eventListenerFactory?.let { builder.eventListenerFactory(it) }
            mBuilder.networkInterceptor?.let { builder.addNetworkInterceptor(it) }

        }
        mBuilder.cookieJarInterceptor?.let {
            builder.cookieJar(it)//添加cookie拦截器
        }
        mBuilder.interceptors?.forEach {
            builder.addInterceptor(it)//添加自定义拦截器
        }
        val client = builder.build()
        //初始化 retrofit
        return Retrofit.Builder()
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            //.addConverterFactory(CustomGsonConverterFactory.create())
            .client(client)
            .baseUrl(mBuilder.baseUrl)
            .build()
    }

    //为OkHttpClient 新增 interceptors
    fun addNetProgressListener(listener: NetDownloadProgressCallBack) {
        mNetProgressListeners.add(listener)
    }

    //为OkHttpClient 移除 interceptors
    fun removeNetProgressListener(listener: NetDownloadProgressCallBack) {
        mNetProgressListeners.remove(listener)
    }

    //新增下载队列  +1
    fun addCurrentDownloadCount() {
        log("新增下载队列 当前队列数：$currentDownloadCount")
        currentDownloadCount++
    }

    //移除下载队列 -1
    fun subCurrentDownloadCount() {
        log("移除下载队列 当前队列数：$currentDownloadCount")
        currentDownloadCount--
    }

    //Buider构造
    class Builder(var context: Context) {
        var baseUrl: String? = null//base
        var applictionId: String? = null //主工程的applictiond
        var maxDownloadCount = 5 //最大下载队列  下载队列。默认最大5
        var debug = false //是否开启调试输出
        var dbName = "net.db"//缓冲数据库,表名
        var connection_Timeout = 6//超时超时-默认6秒
        var read_Timeout = 6//读取超时-默认6秒
        var down_Connection_Time = 30//下载超时-默认30秒
        var netBufferTime = 60//有网情况下的本地缓存时间默认60秒
        var noNetBufferTime = 24 * 60 * 60 * 7//无网络的情况下本地缓存时间默认7天
        var cookieJarInterceptor: CookieJar?=null//cookie拦截器
        var interceptors:ArrayList<Interceptor>?=null//cookie拦截器

        var eventListenerFactory: EventListener.Factory?=null//cookie拦截器
        var networkInterceptor: Interceptor?=null//cookie拦截器

        //接口 baseUrl
        fun setBaseUrl(baseUrl: String?): Builder {
            this.baseUrl = baseUrl
            return this
        }

        //设置主工程 appID，用于7.0 安装apk权限
        fun setApplictionId(applictionId: String?): Builder {
            this.applictionId = applictionId
            return this
        }

        //设置下载队列，最大下载次数
        fun setDownloadsQueueCount(downloadsQueueCount: Int): Builder {
            maxDownloadCount = downloadsQueueCount
            return this
        }

        //是否开启网络请求输出 调试日志
        fun setDebug(debug: Boolean): Builder {
            this.debug = debug
            return this
        }

        //缓冲数据库,表名
        fun setDbName(dbName: String): Builder {
            this.dbName = dbName
            return this
        }

        //超时超时-默认6秒
        fun setConnectionTimeout(connection_Timeout: Int): Builder {
            this.connection_Timeout = connection_Timeout
            return this
        }

        //读取超时-默认6秒
        fun setReadTimeout(read_Timeout: Int): Builder {
            this.read_Timeout = read_Timeout
            return this
        }

        //下载连接超时-默认30秒
        fun setDownConnectionTime(down_Connection_Time: Int): Builder {
            this.down_Connection_Time = down_Connection_Time
            return this
        }

        //有网情况下的本地缓存时间默认60秒
        fun setNetBufferTime(net_Buffer_Time: Int): Builder {
            this.netBufferTime = net_Buffer_Time
            return this
        }

        //无网络的情况下本地缓存时间默认7天
        fun setNoNetBufferTime(no_Net_Buffer_Time: Int): Builder {
            this.noNetBufferTime = no_Net_Buffer_Time
            return this
        }

        //添加cookie拦截器
        fun setCookieJarInterceptor(cookieJarInterceptor: CookieJar?): Builder {
            this.cookieJarInterceptor = cookieJarInterceptor
            return this
        }

        //添加自定义拦截器
        fun setInterceptor(interceptor: Interceptor?): Builder {
            interceptor?.let {
                if (this.interceptors==null){
                    this.interceptors= arrayListOf()
                }
                this.interceptors?.add(it)
            }
            return this
        }

        //配置工厂监听器。主要是计算网络过程消耗时间
        fun setEventListenerFactory(eventListenerFactory: EventListener.Factory): Builder {
           this.eventListenerFactory=eventListenerFactory
            return this
        }

        //主要是处理拦截请求，响应等信息
        fun addNetworkInterceptor(networkInterceptor: Interceptor): Builder {
            this.networkInterceptor=networkInterceptor
            return this
        }

        //初始化完成
        fun build() {
            //检测参数
            if (context == null || applictionId == null) {
                Log.e("tag", "警告：参数配置异常")
                return
            }
            mRetrofitClient = Net(this) //初始化Retrofit
            NetRoomUtil.init(context,dbName)//用户网络缓存数据库初始化
        }
    }

    companion object {
        //private lateinit var mService: Any//普通请求
        private lateinit var mHttpDownService: NetDownloadApi//网络请求
        lateinit var mRetrofitClient: Net //Retrofit
        private val mNetProgressListeners: MutableList<NetDownloadProgressCallBack> = ArrayList() //网络 ->  为了用静态，避免资源回收

        //获取绑定的接口
        fun <T> getService(service: Class<T>): T {
            //if (!this::mService.isInitialized) {
            //    mService = mRetrofitClient.crateRetrofit(false).create(service)!!
            //}
            //return mService as T
            return (mRetrofitClient.crateRetrofit(false).create(service)) as T
        }

        //下载功能
        @JvmStatic
        val downService: NetDownloadApi
            get() {
                if (!this::mHttpDownService.isInitialized) {
                    mHttpDownService = mRetrofitClient.crateRetrofit(true).create(NetDownloadApi::class.java)
                }
                return mHttpDownService
            }

        //获取控制器
        @JvmStatic
        fun client() = mRetrofitClient

        //输出日志
        @JvmStatic
        fun log(message: String?=null) {
            if (client().mBuilder.debug) {
                Log.e("HttpLog", message?:"null")
            }
        }

        @JvmStatic
        fun init(context: Context):Builder{
            val build=Builder(context) //初始化Buider
            HawkSpUtitls.init(context)//初始化Hawk数据库（建值对存储的数据库sp，sqlite双选择）
            NetUtils.init(context,applictionId = build.applictionId)
            return build
        }

        @JvmStatic
        fun destroy(){
            NetUtils.instance.destroy()
        }
    }
}